package com.xc.file.config;

import com.xc.file.api.NoticeApi;
import com.xc.file.bean.FolderBean;
import com.xc.file.bean.NoticeBean;
import com.xc.file.info.FileInfo;
import com.xc.file.info.FolderInfo;
import com.xc.file.info.HashInfo;
import com.xc.tool.utils.Md5Utils;
import com.xc.tool.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * <p>项目名称: Stars</p>
 * <p>描述: 启动成功执行</p>
 * <P>创建人:小程 </p>
 * <P>创建人邮箱: 779943476@qq.com</p>
 * <p>创建时间: 2019/11/14</p>
 *
 * @version v1.0
 */
@Component
@Slf4j
public class StartSuccess implements CommandLineRunner {
    @Autowired
    private Constants constants;

    @Autowired
    private NoticeApi noticeApi;

    @Override
    public void run(String... strings) {
        timer();
        initDeleteFile();
        notice();
    }

    /**
     * 定时执行
     */
    private void timer() {
        try {
            Runnable runnable = new Runnable() {
                //创建 run 方法
                public void run() {
                    initDeleteFile();
                    constants.setFileInfoMap(new Hashtable<>());
                    constants.setFileDownloadMap(new Hashtable<>());
                    log.info("定时清除数据完成！");
                }
            };
            ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
            Calendar cal = Calendar.getInstance();
            //每天定点执行
            cal.set(Calendar.HOUR_OF_DAY, 23);
            cal.set(Calendar.MINUTE, 59);
            cal.set(Calendar.SECOND, 59);
            // 第二个参数为首次执行的延时时间，第三个参数为定时执行的间隔时间
            service.scheduleAtFixedRate(runnable, cal.getTime().getTime() - new Date().getTime(), 1, TimeUnit.DAYS);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化删除文件
     */
    private void initDeleteFile() {
        try {
            for (FolderInfo folderInfo : constants.getFolderPaths()) {
                String[] fileNames = new File(folderInfo.getPath()).list();
                if (fileNames != null) {
                    for (String fileName : fileNames) {
                        String hashCode = fileName.substring(0, fileName.indexOf("."));
                        String path = folderInfo.getPath() + File.separator + hashCode + constants.getUploadSuffix();
                        File file = new File(path);
                        if (file.exists() && !file.delete()) {
                            log.error("初始化删除文件失败！");
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 向管理服务器发送本地的文件信息
     */
    public void notice() {
        if (constants.getOpenNotice()) {
            try {
                //读取本地的文件信息
                List<HashInfo> hashInfos = new ArrayList<>();
                for (FolderInfo folderInfo : constants.getFolderPaths()) {
                    String path = folderInfo.getPath() + File.separator;
                    File[] files = new File(path).listFiles();
                    if (files != null && files.length != 0) {
                        for (File file : files) {
                            String hashCode = file.getName().substring(0, file.getName().indexOf("."));
                            hashInfos.add(new HashInfo(folderInfo.getPath(), hashCode, file.length()));
                        }
                    }
                }
                //计算可用空间
                List<FolderBean> folderBeans = new ArrayList<>();
                for (FolderInfo folderInfo : constants.getFolderPaths()) {
                    folderBeans.add(getAvailableSpace(folderInfo));
                }
                //发送通知请求
                NoticeBean noticeBean = new NoticeBean();
                noticeBean.setAppId(constants.getAppId());
                noticeBean.setAppSecret(constants.getAppSecret());
                noticeBean.setLocalUrl(constants.getLocalUrl());
                noticeBean.setHashInfos(hashInfos);
                noticeBean.setFolderBeans(folderBeans);
                if (constants.getSecret() == null || constants.getSecret().equals("")) {
                    constants.setSecret(Md5Utils.getSaltMd5(StringUtils.random(6)));
                }
                log.info("访问密钥：{}", constants.getSecret());
                noticeBean.setSecret(constants.getSecret());
                noticeApi.notice(noticeBean);
            } catch (Exception e) {
                log.error("文件注入失败！" + e.getMessage(), e);
                e.printStackTrace();
            }
        }
    }


    /**
     * 获取目录可用空间
     *
     * @param folderInfo 目录信息
     * @return 返回当前目录的可用空间
     */
    private FolderBean getAvailableSpace(FolderInfo folderInfo) {
        long size = 0;
        //计算缓存为上传完成文件大小
        Map<String, FileInfo> fileInfoMap = constants.getFileInfoMap();
        for (String key : fileInfoMap.keySet()) {
            if (folderInfo.getPath().equals(fileInfoMap.get(key).getFilePath())) {
                size += fileInfoMap.get(key).getSize();
            }
        }
        File file = new File(folderInfo.getPath());
        //创建目录
        if (!file.exists()) {
            if (!file.mkdirs()) {
                log.error("初始化创建目录失败！");
            }
        }
        if (size == 0) {
            FolderBean folderBean = new FolderBean();
            folderBean.setPath(folderInfo.getPath());
            long availableSpace = file.getFreeSpace() - folderInfo.getReserveSpace();
            folderBean.setAvailableSpace(availableSpace);
            return folderBean;
        } else {
            FolderBean folderBean = new FolderBean();
            folderBean.setPath(folderInfo.getPath());
            long availableSpace = file.getFreeSpace() - folderInfo.getReserveSpace() - size;
            folderBean.setAvailableSpace(availableSpace);
            return folderBean;
        }
    }
}
